<!DOCTYPE html>
<html>
<head>
  <title>drag_test.html</title>
  <script src="test_bootstrap.js"></script>
  <script type="text/javascript">
    goog.require('bot.action');
    goog.require('goog.events');
    goog.require('goog.fx.DragDropGroup');
    goog.require('goog.math.Coordinate');
    goog.require('goog.style');
    goog.require('goog.testing.jsunit');
  </script>

  <style type="text/css">
    div#testDiv,div#testDiv2 {
      width: 40px;
      height: 20px;
      top: 25px;
      left: 300px;
      border: 3px solid #AF0078;
      position: absolute;
    }
    div#testDiv2 {
      top: 10px;
      left: 200px;
      width: 200px;
      height: 100px;
      z-index: -1;
    }
  </style>

  <script type="text/javascript">
    function testClosureFxDragAndDrop() {
      // Setup Drag and Drop using goog.fx
      var testDiv = document.getElementById('testDiv');
      var testDiv2 = document.getElementById('testDiv2');
      var div1 = new goog.fx.DragDropGroup();
      var div2 = new goog.fx.DragDropGroup();
      div1.addItem(testDiv, 'Drag me');
      div2.addItem(testDiv2, 'Destination');
      div1.addTarget(div2);
      div1.init();
      div2.init();

      goog.events.listen(div2, 'drop', function(event) {
        var dragSrc = event.dragSourceItem;
        var elem = event.dragSourceItem.element;
        var pos = goog.style.getClientPosition(elem);
        elem.style.left = pos.x + (event.clientX - dragSrc.startPosition_.x) +
                          'px';
        elem.style.top = pos.y + (event.clientY - dragSrc.startPosition_.y) +
                          'px';
      });

      // Start testing
      var target = document.getElementById('testDiv');
      var coordOld = goog.style.getClientPosition(target);
      var coords = new goog.math.Coordinate(15, 5);
      var dx = -75;
      var dy = 35;
      bot.action.drag(target, dx, dy, coords);

      var coordNew = goog.style.getClientPosition(target);
      assertEquals('Wrong x coordinate', coordNew.x, coordOld.x + dx);
      assertEquals('Wrong y coordinate', coordNew.y, coordOld.y + dy);

      // End of the test
      div1.dispose();
      div2.dispose();
    }

    function elementThatMovesDuringDrag(action) {
      // IE is not compatible with touch actions.
      if (action == bot.action.swipe && !bot.events.SUPPORTS_TOUCH_EVENTS) {
        return;
      }
      // Setup a simple Drag and Drop object
      var DragDropDiv = function(element) {
        this.element_ = element;
        this.dragging_ = false;
        this.x_ = 0;
        this.y_ = 0;
        if (action == bot.action.drag) {
          goog.events.listen(this.element_, goog.events.EventType.MOUSEDOWN,
                             this.startMove, false, this);
          goog.events.listen(this.element_, goog.events.EventType.MOUSEMOVE,
                             this.move, false, this);
          goog.events.listen(this.element_, goog.events.EventType.MOUSEUP,
                             this.endMove, false, this);
        } else {
          goog.events.listen(this.element_, goog.events.EventType.TOUCHSTART,
                             this.startMove, false, this);
          goog.events.listen(this.element_, goog.events.EventType.TOUCHMOVE,
                             this.move, false, this);
          goog.events.listen(this.element_, goog.events.EventType.TOUCHEND,
                             this.endMove, false, this);
        }
      };
      DragDropDiv.prototype.startMove = function(event) {
        this.dragging_ = true;
        if (action == bot.action.drag) {
          this.x_ = event.clientX;
          this.y_ = event.clientY;
        } else {
          var e = event.getBrowserEvent();
          if (e.touches) {
            this.x_ = e.touches[0].clientX;
            this.y_ = e.touches[0].clientY;
          }
        }
      };
      DragDropDiv.prototype.move = function(event) {
        if (this.dragging_) {
          var dx, dy;
          if (action == bot.action.drag) {
            dx = event.clientX - this.x_;
            dy = event.clientY - this.y_;
            this.x_ = event.clientX;
            this.y_ = event.clientY;
          } else {
            var e = event.getBrowserEvent();
            dx = e.touches[0].clientX - this.x_;
            dy = e.touches[0].clientY - this.y_;
            this.x_ = e.touches[0].clientX;
            this.y_ = e.touches[0].clientY;
            event.preventDefault();
          }
          var elementStyle = this.element_.style;
          elementStyle.left = parseInt(elementStyle.left) + dx + 'px';
          elementStyle.top = parseInt(elementStyle.top) + dy + 'px';
        }
      };
      DragDropDiv.prototype.endMove = function(event) {
        this.dragging_ = false;
        if (action == bot.action.drag) {
          this.x_ = event.clientX;
          this.y_ = event.clientY;
        } else {
          var e = event.getBrowserEvent();
          if (e.changedTouches) {
            this.x_ = e.changedTouches[0].clientX;
            this.y_ = e.changedTouches[0].clientY;
          }
        }
      };

      var target = document.getElementById('dragDiv');
      var dragDiv = new DragDropDiv(target);

      // Start testing
      var initPos = goog.style.getClientPosition(target);
      var coords = new goog.math.Coordinate(5, 5);
      var dx = 25;
      var dy = -30;
      action(target, dx, dy, coords);

      var finalPos = goog.style.getClientPosition(target);
      assertEquals(finalPos.x, initPos.x + dx);
      assertEquals(finalPos.y, initPos.y + dy);
    }

    var testDragElementThatMovesDuringDrag = goog.partial(
        elementThatMovesDuringDrag, bot.action.drag);

    var testSwipeElementThatMovesDuringDrag = goog.partial(
        elementThatMovesDuringDrag, bot.action.swipe);
  </script>
</head>
<body>
<div id="testDiv" style="background-color: red;" >Drag</div>
<div id="testDiv2">Drop inside me.</div>
<div id="dragDiv" style="position:fixed; top:50px; left:50px;
  background-color:yellow;"> Drag Me </div>
</body>
</html>
